/*
 * trender.c
 * Asif Shahidullah
 *
 * Contains the implementation of the trend analysis function.
 * Arguably, this function should be in it's own file because 
 * it is not strictly a filter.
 */

#include <stdio.h>

#include "consecutive.h"
#include "d_list.h"
#include "fcompare.h"
#include "list_data.h"
#include "trender.h"

/* Checks if the Node and the two previous (time consectutive)
 * nodes are monotonically decreasing. */
static __inline__ int mnt_tdec(Node);

void analyze_trend (List list) {
	Node a;

	/* Trend analysis cannot be performed on a list with fewer than
	 * three data points. */
	if (list->size < 3) {
		fprintf (stderr, "Attempted trend analysis on diminutive set.\n");
		return;
	}

	/* Special case: if the list size is exactly 3, the below alogrithm
	 * will not work, since it requires a minimum of four data points. */
	else if (list->size == 3) {
		if (mnt_tdec (list->head->next->next)) {
			list->head->data->ac = 1;
			list->head->next->data->ac = 1;
			list->head->next->next->data->ac = 1;
		}
		return;
	}

	/* Main functioning loop: looks for trends and updates the 
	 * LData structure accordingly to reflect any persistant 
	 * trends. */
	a = list->head->next->next;
	while (a != NULL) {
		if (mnt_tdec (a)) {
			if (a->prev->prev->prev != NULL) {
				if (fcompare (a->prev->prev->prev->data->temp, 
							a->prev->prev->data->temp) > 0)  {
					a->prev->prev->data->ac = 1;
					a->prev->data->ac = 1;
					a->data->ac = 1;
				} else
						if (!is_consecutive_data_point (a->prev->prev->prev->data, 
									a->prev->prev->data))
							a->prev->prev->data->ac = 1;
			}
		}
		a = a->next;
	}
}

int mnt_tdec (Node c) {
	LData data_a, data_b, data_c;

	/* Assign all data points: */
	data_a = c->prev->prev->data;
	data_b = c->prev->data;
	data_c = c->data;

	/* Check for time consistency: */
	if (!is_consecutive_data_point(data_a, data_b) ||
			!is_consecutive_data_point(data_b, data_c))
		return 0;

	/* Ensure that we have a decreasing data set. */
	if (((fcompare (data_a->temp, data_b->temp) > 0) &&
			(fcompare (data_b->temp, data_c->temp) > 0)))
		return 1;

	return 0;
}
